Skip to content

Mega super hyper cleanup - #956

Merged
aaltat merged 12 commits into
robotframework:masterfrom
pekkaklarck:element-cleanup
Oct 19, 2017
Merged

aaltat merged 12 commits into
robotframework:masterfrom
pekkaklarck:element-cleanup

Conversation

@pekkaklarck

@pekkaklarck pekkaklarck commented Oct 13, 2017 •

Copy link
Copy Markdown
Member

Cleanup to docs and code here and there. See commit messages of individual commits for details. Sorry for some of the commits grewing unfortunately large.

- Remove unnecessary coupling between Element and FormElement keywords.
- Enhance related error message.
- Enhance documentation of ElementKeywords (robotframework#925).
- Add '.' at the end of error and log messages.
- Introduce `ContextsAware.find_elements` helper.
- Change default value of optional `message` from '' to None.
- Use `is_noney` instead of `is_falsy` when default value is None.
- General (and trivial) cleanup to code and tests.
Also added more XPath examples. This ought to cover enhancements
proposed by robotframework#940.
- Doc string to `find_element`. Mainly to give type hits to IDE but
  higher level APIs should get more docs in general.
- Introduced ElementNotFound error that `ElementFinder.find` uses.
- Move helpers to ContextAware and LibraryComponent to avoid
  unnecessary coupling between different library componets.
- Remove unnecessary helpers when `find_element(locator).method()`
  works as well.
- Rewriter internal logic with `Wait` keywords. This includes
  consistently handling non-existing elements.
- Make unregistering strategy that hasn't been registered an error.
- Consider `<input type="file">` text element consistently.
- General cleanup here and there.
@aaltat

aaltat commented Oct 18, 2017

Copy link
Copy Markdown
Contributor

Did only read to waiting object, but have few comments

"Element Should (Not) Be Enabled" and "Wait Until Element Is Enabled"
now all validate that the element is enabled and not readonly. Also
removed broken element type validation from the former keywords.

Fixes robotframework#958.
@pekkaklarck pekkaklarck changed the title Cleanup to ElementKeywords (and elsewhere) Mega super cleanup Oct 18, 2017
@pekkaklarck pekkaklarck changed the title Mega super cleanup Mega super hyper cleanup Oct 18, 2017

@aaltat aaltat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did all the changes.

Comment thread src/SeleniumLibrary/keywords/element.py Outdated
@keyword
def current_frame_should_not_contain(self, text, loglevel='INFO'):
"""Verifies that current frame contains `text`.
"""Verifies that current frame contains ``text``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be not somewhere in the sentence?

Comment thread src/SeleniumLibrary/keywords/frames.py Outdated

@keyword
def current_frame_should_not_contain(self, text, loglevel='INFO'):
"""Verifies that current frame contains ``text``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think doc string is missing text: not

try:
if condition():
return
except ElementNotFound as err:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that this code could resolve the StaleElementReferenceException if we would suppress also that exception. If it does, perhaps we should look us there other exceptions that could be also suppress.

Comment thread src/SeleniumLibrary/errors.py Outdated
# limitations under the License.


class ElementNotFound(Exception):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having own exception is really good idea.

I think in future it is possible that we have more exceptions and because it provides better information for the user. But for programmatic, I often have to need suppress all from specific class. Therefore it might be useful to have some base error class for SeleniumLibrary exceptions. Like:

class BaseException(Exception):
    ROBOT_SUPPRESS_NAME = True


class ElementNotFound(BaseException):
    pass

Then in libraries which extend SL, I could do:

try:
    self.sl.some_method(arg1, arg2...)
expect BaseException:
    do_something_else(ar3)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I'll add SeleniumLibraryException base class.

using the log level specified with the optional ``loglevel``
argument. Valid log levels are ``DEBUG``, ``INFO`` (default),
``WARN``, and ``NONE``. If the log level is ``NONE`` or below
the current active log level the source will not be logged.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be useful to mention that text is verified from the DOM tree which sometimes may differ what is seen in the page. Example the case of the text might be different in the DOM, than what is seen in the page. Other valid example if the text is split to multiple elements, example there is link in the middle of the text, then keyword can not find the whole text. Instead the search must be divided between each element.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about the problem with finding text with elements in them? I just changed our test data to contain This is the haystack and somewhere on this page is a <em>needle</em>. and

Page Should Contain    This is the haystack and somewhere on this page is a needle.

seems to work just fine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did have recollection that in some point it did not work, but I ques it does not hold water anymore. But the first point is a valid one and sometimes causes questions in the user group or in the issue tracker.

Comment thread src/SeleniumLibrary/keywords/element.py Outdated
def page_should_not_contain_link(self, locator, message='', loglevel='INFO'):
"""Verifies image identified by `locator` is not found from current page.
def page_should_not_contain_link(self, locator, message=None, loglevel='INFO'):
"""Verifies image identified by ``locator`` is not found from current page.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change "image" to "link"


@keyword
def wait_until_element_is_enabled(self, locator, timeout=None, error=None):
"""Waits until element specified with `locator` is enabled.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`locator ` to ``locator``

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't gone through these docs yet.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem.


Fails if `timeout` expires before the element is enabled. See
`introduction` for more information about `timeout` and its
Fails if `timeout` expires before the element is enabled. Element

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`timeout` to ``timeout``

See `introduction` for more information about `timeout` and its
default value.

`error` can be used to override the default error message.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`error` to ``error``

else:
del self._strategies[strategy_name]
if strategy_name not in self._strategies:
raise RuntimeError("Cannot unregister the non-registered strategy '%s'."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be issue about this change? It by a quick look feels backwards incompatible change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so. Submitted #961.

- User `find_elements` instead of `find_element` when possible.
- Avoid `strategy=value` locator syntax in code.
- Enhance error messages when radio buttons not found.
- Cleanup `Choose File` test and test it with Firefox.
- TableElementFinder._locator to public class variable.
- Remove useless documentation.
@aaltat
aaltat merged commit 4e48199 into robotframework:master Oct 19, 2017
@pekkaklarck
pekkaklarck deleted the element-cleanup branch October 23, 2017 11:43
@pekkaklarck
pekkaklarck restored the element-cleanup branch October 23, 2017 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants